/*
This is part of Screenbar, which is based in part on the Litestep
shell source code.

Copyright (C) 2008-2009 Jim Babcock
Copyright (C) 1997-2009 The LiteStep Development Team

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include "stdafx.h"

#define BRANCH_EXPR(name, expr) \
	class name :public BranchElement::BranchExpression { \
		bool evaluate(const ElementContext *context) { \
			return(expr); \
		} \
	}

class BranchExpression_windowHover
	:public BranchElement::BranchExpression
{
	bool evaluate(const ElementContext *context)
	{
		TaskData *task = getHoveredTask();
		if(!task) return false;
		
		WindowData *window = context->getTask();
		return task->containsWindow(window);
	}
};

BranchElement::BranchExpression *BranchElement::parseLeafExpression(const string &expr)
{
	const char *token = expr.c_str();
	
	BRANCH_EXPR(TrueCondition, true);
	BRANCH_EXPR(FalseCondition, false);
	
	if(!_stricmp(token, "minimized"))
	{
		BRANCH_EXPR(MinimizedCondition, context->getTask() && context->getTask()->isMinimized());
		return new MinimizedCondition();
	}
	else if(!_stricmp(token, "thismonitor"))
	{
		BRANCH_EXPR(ThisMonitorCondition,
			context->desk && context->desk->getMonitor()==context->monitor);
		return new ThisMonitorCondition();
	}
	else if(!_stricmp(token, "focused"))
	{
		BRANCH_EXPR(FocusedCondition,
			(context->getTask() && context->getTask()->isFocusedTask())
			|| (!context->getTask() && context->desk && context->desk->isVisible()));
		return new FocusedCondition();
	}
	else if(!_stricmp(token, "deskfocused"))
	{
		BRANCH_EXPR(DeskFocusedCondition,
			(context->desk && context->desk->isVisible()));
		return new DeskFocusedCondition();
	}
	else if(!_stricmp(token, "true"))
	{
		return new TrueCondition();
	}
	else if(!_stricmp(token, "false"))
	{
		return new FalseCondition();
	}
	else if(!_stricmp(token, "dragging"))
	{
		BRANCH_EXPR(DraggingCondition, dragState.isDragging());
		return new DraggingCondition();
	}
	else if(!_stricmp(token, "flashing"))
	{
		BRANCH_EXPR(FlashingCondition,
			(context->getTask() && context->getTask()->flashing));
		return new FlashingCondition();
	}
	else if(!_stricmp(token, "hovered"))
	{
		BRANCH_EXPR(HoveredCondition, context->hovered);
		return new HoveredCondition();
	}
	else if(!_stricmp(token, "vertical"))
	{
		BRANCH_EXPR(VerticalCondition, context->vertical);
		return new VerticalCondition();
	}
	else if(!_stricmp(token, "windowhovered"))
	{
		enableHoverTracking();
		return new BranchExpression_windowHover();
	}
	else
	{
		if(getConfigBool("UpdateVars", false, prefix.c_str()))
		{
			class VarCondition
				:public BranchElement::BranchExpression
			{
			public:
				VarCondition(string varname)
					:varname(varname) {}
				bool evaluate(const ElementContext *context)
					{ return getConfigBool(varname.c_str(), false, ""); }
			private:
				string varname;
			};
			return new VarCondition(expr);
		}
		else
		{
			if(getConfigBool(expr.c_str(), false, ""))
				return new TrueCondition();
			else
				return new FalseCondition();
		}
	}
}
